﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PhutoiTieu
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public FSET[] layfth(string futhuocham)
        {

            string b = futhuocham;
            SET Left; SET Right;
            string[] fth = txt_F.Text.Split(';');
            int n = fth.Length;
            FSET[] fs = new FSET[n];
            string templeft;
            string tempright;
            for (int i = 0; i < n; i++)
            {
                int k = fth[i].IndexOf("->");
                templeft = fth[i].Substring(0, k);
                Left = new SET(templeft.ToCharArray());
                tempright = fth[i].Substring(k + 2);
                Right = new SET(tempright.ToCharArray());
                fs[i] = new FSET(Left, Right);
            }
            return fs;

        }
        public SET tinhbd(FSET[] fs, SET x)
        {
            int n = fs.Length;
            SET baodong = new SET(x.Att);
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                {
                    if (baodong.check(fs[j].Left.Att))
                        baodong.AddAtt(fs[j].Right.Att);
                }
            return baodong;
        }
        public FSET[] xoa1fs(FSET[] fs, int k)
        {
            if (fs == null)
            {
                return fs;
            }
            else
            {
                FSET[] g = new FSET[fs.Length - 1];
                for (int i = 0; i < k; i++)

                    g[i] = new FSET(fs[i].Left, fs[i].Right);

                for (int i = k; i < fs.Length - 1; i++)
                    g[i] = new FSET(fs[i + 1].Left, fs[i + 1].Right);

                return g;
            }
        }
        public FSET[] them1fs(FSET[] fs, FSET f)
        {
            FSET[] G = new FSET[fs.Length + 1];
            for (int i = 0; i < fs.Length; i++)
                G[i] = new FSET(fs[i].Left, fs[i].Right);
            G[fs.Length] = new FSET(f.Left, f.Right);
            return G;
        }
        public string xuatmangfs(FSET[] fs)
        { 
            string a="";
            for (int i = 0; i < fs.Length - 1; i++)
                a += fs[i]+";";
            a += fs[fs.Length - 1];
            return a;

        }
        public FSET[] tachvephai(FSET[] fs)
        {
           FSET[] g= new FSET[0];
            for( int i=0;i<fs.Length; i++)
                if (fs[i].Right.Att.Length > 1)
                {
                    for (int j = 0; j < fs[i].Right.Att.Length; j++)
                    {
                        string a = fs[i].Right.Att[j].ToString();
                        SET right = new SET(a.ToCharArray());
                        FSET temp = new FSET(fs[i].Left, right);
                        g = them1fs(g, temp);
                    }
                }
                else
                {
                    g = them1fs(g, fs[i]);
                }
            return g;
        }
        public FSET[] xoafthduthua(FSET[] fs)
        {
            int n = fs.Length;
            for (int i = 0; i < n; i++)
            { 
                FSET[] g= xoa1fs(fs,i);
                if (tinhbd(g, fs[i].Left).check(fs[i].Right.Att))
                {
                    fs = xoa1fs(fs, i);
                    i--;
                    n--;
                }
            }
            return fs;
        }
        public FSET[] themfsvitri(FSET[] fs,FSET f, int k)
        {
            FSET[] g= new FSET[fs.Length+1];
            for (int i = 0; i < k; i++)
            {
                g[i] = new FSET(fs[i].Left, fs[i].Right);
            }
            g[k]=new FSET(f.Left,f.Right);
            for (int i = k ; i < fs.Length; i++)
            {
                g[i + 1] = new FSET(fs[i].Left, fs[i].Right);
            }
            return g;

        }
        public FSET[] xoathuoctinhduthua(FSET[] fs)
        {
            for (int i = 0; i < fs.Length; i++)
            {
                int k=fs[i].Left.Att.Length;
                FSET[] g = xoa1fs(fs, i);
                for (int j = 0; j < k; j++)
                {
                    string kitukiemtra = fs[i].Left.Att[j].ToString();
                    string kituxet = fs[i].Left.ToString().Substring(0, j) + fs[i].Left.ToString().Substring(j + 1);
                    SET xet= new SET(kituxet.ToCharArray());
                    if(tinhbd(g,xet).check(kitukiemtra.ToCharArray()))
                    {
                        FSET xetfs = new FSET(xet, fs[i].Right);
                        fs = xoa1fs(fs, i);
                        fs = themfsvitri(fs, xetfs, i);
                        j--;k--;
                    }
                }
            }
            return fs;
        }
        public bool FindAndTestAttOfF(SET u, FSET[] fs)
        {
            int n = fs.Length;
            SET U = new SET(txt_u.Text.ToCharArray());
            string ttt = "";
            for (int i = 0; i < n; i++)
            {
                ttt += fs[i].Left.ToString();
                ttt += fs[i].Right.ToString();
            }
            char[] UF = ttt.ToCharArray();
            if (U.check(UF)) return true;
            else return false;

        }

        private void btn_tinh_Click(object sender, EventArgs e)
        {
            if (txt_x.Text == "") MessageBox.Show("Mời bạn nhập thuộc tính cần tính bao đóng");
            else
            {
                txt_baodong.Text = "";
                FSET[] fs;
                SET baodong;
                SET u = new SET(txt_u.Text.ToCharArray());
                SET x = new SET(txt_x.Text.ToCharArray());
                try
                {
                    fs = layfth(txt_F.Text);
                    baodong = tinhbd(fs, x);
                    if (FindAndTestAttOfF(u, fs))
                    {
                        if (baodong.checkatt())
                            txt_baodong.Text = baodong.ToString();
                        else MessageBox.Show("Bạn đã nhập sai", "Lỗi nhập");
                    }
                    else MessageBox.Show("Thuộc tính F không thuộc U", "Lỗi");
                }
                catch
                {
                    MessageBox.Show("Bạn đã nhập sai", "Lỗi nhập");
                }
            }
        }

        private void btn_TinhPhuToiTieu_Click(object sender, EventArgs e)
        {
            if (txt_F.Text == "") MessageBox.Show("Mời bạn nhập các phụ thuộc hàm");
            else
            {
                FSET[] fs;
                SET u = new SET(txt_u.Text.ToCharArray());
                try
                {
                    fs = layfth(txt_F.Text);
                    fs = tachvephai(fs);
                    fs = xoafthduthua(fs);
                    fs = xoathuoctinhduthua(fs);
                    if (FindAndTestAttOfF(u, fs))
                    {
                        txt_phutoitieu.Text = xuatmangfs(fs);
                        
                    }
                    else MessageBox.Show("Thuộc tính F không thuộc U", "Lỗi");
                }
                catch
                {
                    MessageBox.Show("Bạn đã nhập sai", "Lỗi nhập");
                }
            }
        }

    
    }
}
